#ifndef V2_NIM_COMPATIBLE_UTILITIES_H
#define V2_NIM_COMPATIBLE_UTILITIES_H
#include "v2_nim_internal.hpp"
#include "wrapper/nim_cpp_wrapper/helper/nim_talk_helper.h"
namespace v2 {
/// @brief 数据结构转换工具
class DataStructureConverter {
public:
    /// @brief V2消息转换为V1
    /// @param message V2消息
    /// @return nim::IMMessage
    /// @par 示例代码
    /// @code
    /// auto message = V2NIMMessageCreator::createTextMessage("hello world");
    /// auto v1Message = DataStructureConverter::messageConvertToV1(message);
    /// @endcode
    static nim::IMMessage messageConvertToV1(const V2NIMMessage& message);

    /// @brief V1消息转换为V2
    /// @param message V1消息
    /// @return V2NIMMessage
    /// @par 示例代码
    /// @code
    /// nim::IMMessage message;
    /// auto v2Message = DataStructureConverter::messageConvertToV2(message);
    /// @endcode
    static V2NIMMessage messageConvertToV2(const nim::IMMessage& message);
};

// NOLINTBEGIN
inline nim::IMMessage DataStructureConverter::messageConvertToV1(const V2NIMMessage& message) {
    nim::IMMessage v1Message;
    v1Message.rescode_ = nim::kNIMResSuccess;
    v1Message.feature_ = nim::kNIMMessageFeatureDefault;
    if (message.conversationType == V2NIM_CONVERSATION_TYPE_P2P) {
        v1Message.session_type_ = nim::kNIMSessionTypeP2P;
    } else if (message.conversationType == V2NIM_CONVERSATION_TYPE_TEAM) {
        v1Message.session_type_ = nim::kNIMSessionTypeTeam;
    } else if (message.conversationType == V2NIM_CONVERSATION_TYPE_SUPER_TEAM) {
        v1Message.session_type_ = nim::kNIMSessionTypeSuperTeam;
    }
    v1Message.receiver_accid_ = message.receiverId;
    v1Message.sender_accid_ = message.senderId;
    v1Message.timetag_ = static_cast<int64_t>(message.createTime);
    v1Message.content_ = message.text;
    v1Message.type_ = static_cast<nim::NIMMessageType>(message.messageType);
    if (message.attachment) {
        v1Message.attach_ = message.attachment->raw;
    }
    v1Message.client_msg_id_ = message.messageClientId;
    v1Message.msg_setting_.server_history_saved_ = message.messageConfig.historyEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.roaming_ = message.messageConfig.roamingEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.self_sync_ = message.messageConfig.onlineSyncEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.need_push_ = message.pushConfig.pushEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.push_need_badge_ = message.messageConfig.unreadEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.push_need_prefix_ = message.pushConfig.pushNickEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.routable_ = message.routeConfig.routeEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.need_offline_ = message.messageConfig.offlineEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.push_payload_ = message.pushConfig.pushPayload.c_str();
    v1Message.msg_setting_.push_content_ = message.pushConfig.pushContent;
    v1Message.msg_setting_.server_ext_ = message.serverExtension ? message.serverExtension->c_str() : "";
    v1Message.msg_setting_.local_ext_ = message.localExtension ? *message.localExtension : "";
    v1Message.msg_setting_.is_force_push_ = message.pushConfig.forcePush ? BS_TRUE : BS_FALSE;
    for (auto&& forcePushAccountId : message.pushConfig.forcePushAccountIds) {
        v1Message.msg_setting_.force_push_ids_list_.push_back(forcePushAccountId);
    }
    v1Message.msg_setting_.force_push_content_ = message.pushConfig.forcePushContent;
    v1Message.msg_setting_.anti_spam_enable_ = message.antispamConfig.antispamEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.anti_spam_content_ = message.antispamConfig.antispamCustomMessage ? *message.antispamConfig.antispamCustomMessage : "";
    v1Message.msg_setting_.anti_apam_biz_id_ = message.antispamConfig.antispamBusinessId ? *message.antispamConfig.antispamBusinessId : "";
    v1Message.msg_setting_.yidun_anti_cheating_ = message.antispamConfig.antispamCheating ? *message.antispamConfig.antispamCheating : "";
    v1Message.msg_setting_.anti_apam_using_yidun_ = message.antispamConfig.antispamEnabled ? 1 : 0;
    v1Message.msg_setting_.anti_spam_ext = message.antispamConfig.antispamExtension ? *message.antispamConfig.antispamExtension : "";
    v1Message.msg_setting_.team_msg_need_ack_ = message.messageConfig.readReceiptEnabled ? BS_TRUE : BS_FALSE;
    v1Message.msg_setting_.is_update_session_ = message.messageConfig.lastMessageUpdateEnabled ? BS_TRUE : BS_FALSE;

    v1Message.third_party_callback_ext_ = message.callbackExtension ? *message.callbackExtension : "";
    v1Message.sub_type_ = static_cast<int32_t>(message.subType);
    v1Message.local_talk_id_ = V2NIMConversationIdUtil::parseConversationTargetId(message.conversationId);
    if (message.sendingState) {
        if (*message.sendingState == V2NIM_MESSAGE_SENDING_STATE_FAILED) {
            v1Message.status_ = nim::kNIMMsgLogStatusSendFailed;
        } else if (*message.sendingState == V2NIM_MESSAGE_SENDING_STATE_SENDING) {
            v1Message.status_ = nim::kNIMMsgLogStatusSending;
        }
    }
    if (message.threadReply) {
        v1Message.thread_info_.reply_msg_from_account_ = message.threadReply->senderId;
        v1Message.thread_info_.reply_msg_to_account_ = message.threadReply->receiverId;
        v1Message.thread_info_.reply_msg_time_ = message.threadReply->createTime;
        v1Message.thread_info_.reply_msg_id_server_ = std::stoull(message.threadReply->messageServerId);
        v1Message.thread_info_.reply_msg_id_client_ = message.threadReply->messageClientId;
    }
    if (message.threadRoot) {
        v1Message.thread_info_.thread_msg_from_account_ = message.threadRoot->senderId;
        v1Message.thread_info_.thread_msg_to_account_ = message.threadRoot->receiverId;
        v1Message.thread_info_.thread_msg_time_ = message.threadRoot->createTime;
        v1Message.thread_info_.thread_msg_id_server_ = std::stoull(message.threadRoot->messageServerId);
        v1Message.thread_info_.thread_msg_id_client_ = message.threadRoot->messageClientId;
    }
    v1Message.robot_info_.account_ = message.robotConfig.accountId ? *message.robotConfig.accountId : "";
    v1Message.robot_info_.function_ = message.robotConfig.function ? *message.robotConfig.function : "";
    v1Message.robot_info_.topic_ = message.robotConfig.topic ? *message.robotConfig.topic : "";
    v1Message.robot_info_.custom_content_ = message.robotConfig.customContent ? *message.robotConfig.customContent : "";
    v1Message.readonly_server_id_ = std::stoull(message.messageServerId);
    return v1Message;
}
inline V2NIMMessage DataStructureConverter::messageConvertToV2(const nim::IMMessage& message) {
    V2NIMMessage v2Message;
    v2Message.conversationType = V2NIM_CONVERSATION_TYPE_UNKNOWN;
    if (message.session_type_ == nim::kNIMSessionTypeP2P) {
        v2Message.conversationType = V2NIM_CONVERSATION_TYPE_P2P;
        v2Message.conversationId = V2NIMConversationIdUtil::p2pConversationId(message.local_talk_id_);
    } else if (message.session_type_ == nim::kNIMSessionTypeTeam) {
        v2Message.conversationType = V2NIM_CONVERSATION_TYPE_TEAM;
        v2Message.conversationId = V2NIMConversationIdUtil::teamConversationId(message.local_talk_id_);
    } else if (message.session_type_ == nim::kNIMSessionTypeSuperTeam) {
        v2Message.conversationType = V2NIM_CONVERSATION_TYPE_SUPER_TEAM;
        v2Message.conversationId = V2NIMConversationIdUtil::superTeamConversationId(message.local_talk_id_);
    }
    v2Message.receiverId = message.receiver_accid_;
    v2Message.senderId = message.sender_accid_;
    v2Message.createTime = static_cast<uint64_t>(message.timetag_);
    v2Message.text = message.content_;
    v2Message.messageType = static_cast<V2NIMMessageType>(message.type_);
    v2Message.attachment = nstd::make_shared<V2NIMMessageAttachment>();
    v2Message.attachment->raw = message.attach_;
    v2Message.messageClientId = message.client_msg_id_;
    v2Message.messageConfig.historyEnabled = message.msg_setting_.server_history_saved_ == BS_TRUE;
    v2Message.messageConfig.roamingEnabled = message.msg_setting_.roaming_ == BS_TRUE;
    v2Message.messageConfig.onlineSyncEnabled = message.msg_setting_.self_sync_ == BS_TRUE;
    v2Message.pushConfig.pushEnabled = message.msg_setting_.need_push_ == BS_TRUE;
    v2Message.messageConfig.unreadEnabled = message.msg_setting_.push_need_badge_ == BS_TRUE;
    v2Message.pushConfig.pushNickEnabled = message.msg_setting_.push_need_prefix_ == BS_TRUE;
    v2Message.routeConfig.routeEnabled = message.msg_setting_.routable_ == BS_TRUE;
    v2Message.messageConfig.offlineEnabled = message.msg_setting_.need_offline_ == BS_TRUE;
    v2Message.pushConfig.pushPayload = message.msg_setting_.push_payload_.toStyledString();
    v2Message.serverExtension = message.msg_setting_.server_ext_.toStyledString();
    v2Message.pushConfig.pushContent = message.msg_setting_.push_content_;
    v2Message.localExtension = message.msg_setting_.local_ext_;
    v2Message.pushConfig.forcePush = message.msg_setting_.is_force_push_ == BS_TRUE;
    for (auto&& forcePushAccountId : message.msg_setting_.force_push_ids_list_) {
        v2Message.pushConfig.forcePushAccountIds.push_back(forcePushAccountId);
    }
    v2Message.pushConfig.forcePushContent = message.msg_setting_.force_push_content_;
    v2Message.antispamConfig.antispamEnabled = message.msg_setting_.anti_spam_enable_ == BS_TRUE;
    v2Message.antispamConfig.antispamCustomMessage = message.msg_setting_.anti_spam_content_;
    v2Message.antispamConfig.antispamBusinessId = message.msg_setting_.anti_apam_biz_id_;
    v2Message.antispamConfig.antispamCheating = message.msg_setting_.yidun_anti_cheating_;
    v2Message.antispamConfig.antispamEnabled = message.msg_setting_.anti_apam_using_yidun_ == 1;
    v2Message.antispamConfig.antispamExtension = message.msg_setting_.anti_spam_ext;
    v2Message.messageConfig.readReceiptEnabled = message.msg_setting_.team_msg_need_ack_ == BS_TRUE;
    v2Message.messageConfig.lastMessageUpdateEnabled = message.msg_setting_.is_update_session_ == BS_TRUE;
    v2Message.callbackExtension = message.third_party_callback_ext_;
    v2Message.subType = message.sub_type_;
    if (message.status_ == nim::kNIMMsgLogStatusSendFailed) {
        v2Message.sendingState = V2NIM_MESSAGE_SENDING_STATE_FAILED;
    } else if (message.status_ == nim::kNIMMsgLogStatusSending) {
        v2Message.sendingState = V2NIM_MESSAGE_SENDING_STATE_SENDING;
    }
    if (!message.thread_info_.reply_msg_from_account_.empty()) {
        v2Message.threadReply = V2NIMMessageRefer();
        v2Message.threadReply->senderId = message.thread_info_.reply_msg_from_account_;
        v2Message.threadReply->receiverId = message.thread_info_.reply_msg_to_account_;
        v2Message.threadReply->createTime = message.thread_info_.reply_msg_time_;
        v2Message.threadReply->messageServerId = std::to_string(message.thread_info_.reply_msg_id_server_);
        v2Message.threadReply->messageClientId = message.thread_info_.reply_msg_id_client_;
    }
    if (!message.thread_info_.thread_msg_from_account_.empty()) {
        v2Message.threadRoot = V2NIMMessageRefer();
        v2Message.threadRoot->senderId = message.thread_info_.thread_msg_from_account_;
        v2Message.threadRoot->receiverId = message.thread_info_.thread_msg_to_account_;
        v2Message.threadRoot->createTime = message.thread_info_.thread_msg_time_;
        v2Message.threadRoot->messageServerId = std::to_string(message.thread_info_.thread_msg_id_server_);
        v2Message.threadRoot->messageClientId = message.thread_info_.thread_msg_id_client_;
    }
    v2Message.robotConfig.accountId = message.robot_info_.account_;
    v2Message.robotConfig.function = message.robot_info_.function_;
    v2Message.robotConfig.topic = message.robot_info_.topic_;
    v2Message.robotConfig.customContent = message.robot_info_.custom_content_;
    v2Message.messageServerId = std::to_string(message.readonly_server_id_);
    return v2Message;
}
// NOLINTEND
}  // namespace v2
#endif